package com.wondream.myframework.app.common.util;

import cn.hutool.core.util.ReflectUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author wangjun
 * @note 函数式编程
 * @date 2024-04-19  16:48
 */
public class ReflectionUtil extends ReflectUtil {

    private static final String SETTER_PREFIX = "set";

    private static final String GETTER_PREFIX = "get";

    /**
     * 调用Getter方法.
     * 支持多级，如：对象名.对象名.方法
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeGetter(Object obj, String propertyName) {
        Object object = obj;
        for (String name : StringUtils.split(propertyName, ".")) {
            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
            object = invoke(object, getterMethodName);
        }
        return (E) object;
    }

    /**
     * 调用Setter方法, 仅匹配方法名。
     * 支持多级，如：对象名.对象名.方法
     */
    public static <E> void invokeSetter(Object obj, String propertyName, E value) {
        Object object = obj;
        String[] names = StringUtils.split(propertyName, ".");
        for (int i = 0; i < names.length; i++) {
            if (i < names.length - 1) {
                String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
                object = invoke(object, getterMethodName);
            } else {
                String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
                Method method = getMethodByName(object.getClass(), setterMethodName);
                invoke(object, method, value);
            }
        }
    }

    /**
     * 反射获取字符串
     * @param field
     * @param target
     * @return
     */
    public static String getFieldAsString(Field field, @Nullable Object target) {
        Object fieldValue = ReflectionUtils.getField(field, target);
        if (fieldValue == null) {
            return StringUtils.EMPTY;
        }
        return String.valueOf(fieldValue);
    }

    /**
     * 查找field并设置可访问
     * @param clazz
     * @param fieldName
     * @return
     */
    public static Field findFieldAndSetAccessable(Class<?> clazz, String fieldName) {
        Field field = ReflectionUtils.findField(clazz, fieldName);
        boolean idAccess = field.isAccessible();
        field.setAccessible(true);
        return field;
    }

    public static void main(String[] args) {
//        Field parentField = ReflectionUtils.findField(DictionaryTreeVo.class, "dictionaryParentId");
//        DictionaryTreeVo var1 = new DictionaryTreeVo();
//        var1.setDictionaryParentId("11111111");
//        System.out.println(ReflectionUtil.getFieldAsString(parentField, var1));
    }
}
